package com.cj.quantum.audiochan;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;

import java.nio.ByteBuffer;
import java.util.Date;

import io.agora.rtc2.ChannelMediaOptions;
import io.agora.rtc2.IRtcEngineEventHandler;
import io.agora.rtc2.RtcEngine;
import io.agora.rtc2.RtcEngineConfig;
import io.agora.rtc2.video.VideoCanvas;

public class MainActivity extends AppCompatActivity {
    // 填写项目的 App ID，可在 Agora 控制台中生成。
    private String appId = "475df61718c844299d0d243fe5fc56e1";
    // 填写频道名称。
    private String channelName = "demo_22";
    // 填写 Agora 控制台中生成的临时 Token。
    private String token = "007eJxTYMhlMgvYucyU5WWMWdYq+zk1/3mLW/de1HT9+maJ7h+1QyUKDCbmpilpZobmhhbJFiYmRpaWKQYpRibGaammacmmZqmGr9l8kxsDGRn+WB1iZGSAQBCfnSElNTc/3siIgQEAd30f5A==";
    // RTC
    private RtcEngine mRtcEngine;
    // 发送线程
    private SendThread sendThread = new SendThread();
    // 接收线程
    private PullThread pullThread = new PullThread();

    public static String bytes2hex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        String tmp = null;
        for (byte b : bytes) {
            // 将每个字节与0xFF进行与运算，然后转化为10进制，然后借助于Integer再转化为16进制
            tmp = Integer.toHexString(0xFF & b);
            if (tmp.length() == 1) {
                tmp = "0" + tmp;
            }
            sb.append(tmp);
        }
        return sb.toString();
    }

    private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
        @Override
        // 监听频道内的远端主播，获取主播的 uid 信息。
        public void onUserJoined(int uid, int elapsed) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 用户成功加入
                    System.out.println("onUserJoined");
                }
            });
        }

        @Override
        public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
            super.onJoinChannelSuccess(channel, uid, elapsed);
            new Thread(sendThread).start();
            new Thread(pullThread).start();
        }
    };

    private static final int PERMISSION_REQ_ID = 22;
    private static final String[] REQUESTED_PERMISSIONS = {
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA
    };

    private boolean checkSelfPermission(String permission, int requestCode) {
        if (ContextCompat.checkSelfPermission(this, permission) !=
                PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
            return false;
        }
        return true;
    }

    private void initializeAndJoinChannel() {
        try {
            RtcEngineConfig config = new RtcEngineConfig();
            config.mContext = getBaseContext();
            config.mAppId = appId;
            config.mEventHandler = mRtcEventHandler;
            mRtcEngine = RtcEngine.create(config);
        } catch (Exception e) {
            throw new RuntimeException("Check the error.");
        }

        // 指定自定义音频源
        mRtcEngine.setExternalAudioSource(true, 16000, 1, 1, true, true);

        // 指定接收的音频源头
        mRtcEngine.setExternalAudioSink(
                true,      // 开启自定义音频渲染
                16000,   // 采样率（Hz）。你可以将该值设置为 16000，32000，441000 或者 48000
                1          // 自定义音频源的声道数。你可以将该值设置为 1 或 2
        );

        // 本地用户加入频道
        ChannelMediaOptions option = new ChannelMediaOptions();
        option.autoSubscribeAudio = true;
        option.autoSubscribeVideo = true;
        int res = mRtcEngine.joinChannel(token, channelName, 0, option);
        if (res != 0) {
            System.out.println("本地用户加入频道，出现错误:" + res);
        } else {
            System.out.println("成功加入频道");
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 如果已经授权，则初始化 RtcEngine 并加入频道。
        if (checkSelfPermission(REQUESTED_PERMISSIONS[0], PERMISSION_REQ_ID) &&
                checkSelfPermission(REQUESTED_PERMISSIONS[1], PERMISSION_REQ_ID)) {
            // 初始化成功加入频道
            initializeAndJoinChannel();
        }
    }

    private class SendThread implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // 帧数据
                byte[] newBuffer = new byte[160];
                for (int i = 0; i < 160; i++) {
                    newBuffer[i] = 0x0B;
                }

                // 帧时间戳
                long timestamp = new Date().getTime();

                int ret = mRtcEngine.pushExternalAudioFrame(newBuffer, timestamp);
                if (ret != 0) {
                    System.out.println("发送失败...");
                } else {
                    System.out.println(timestamp);
                    System.out.println("帧发送成功..." + bytes2hex(newBuffer));
                }
            }
        }
    }

    private class PullThread implements Runnable {
        @Override
        public void run() {
            int lengthInByte = 160;

            while (true) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                ByteBuffer frame = ByteBuffer.allocateDirect(lengthInByte);
                int ret = mRtcEngine.pullPlaybackAudioFrame(frame, lengthInByte);
                if (ret != 0) {
                    System.out.println("接收失败...");
                } else {
                    byte[] data = new byte[frame.remaining()];
                    frame.get(data, 0, data.length);
                    System.out.println("接收成功..." + bytes2hex(data));
                }
            }
        }
    }
}